import re

from django.test import TestCase

# Create your tests here.

# # 3 响应数据入库
# {
#     "LatestShipDate": "2019-04-19T06:59:59Z",
#     "OrderType": "StandardOrder",
#     "PurchaseDate": "2019-04-11T17:02:17.325Z",
#     "AmazonOrderId": "702-7273726-4111420",
#     "BuyerEmail": "47h24zbxc77jxjb@marketplace.amazon.ca",
#     "IsReplacementOrder": "false",
#     "LastUpdateDate": "2019-04-12T01:54:26.517Z",
#     "NumberOfItemsShipped": "2",
#     "ShipServiceLevel": "Std CA D2D Dom",
#     "OrderStatus": "Shipped",
#     "SalesChannel": "Amazon.ca",
#     "ShippedByAmazonTFM": "false",
#     "IsBusinessOrder": "false",
#     "LatestDeliveryDate": "2019-06-01T06:59:59Z",
#     "NumberOfItemsUnshipped": "0",
#     "PaymentMethodDetails": {
#         "PaymentMethodDetail": "Standard"
#     },
#     "BuyerName": "kathleen betz",
#     "EarliestDeliveryDate": "2019-05-09T07:00:00Z",
#     "OrderTotal": {
#         "CurrencyCode": "CAD",
#         "Amount": "31.32"
#     },
#     "IsPremiumOrder": "false",
#     "EarliestShipDate": "2019-04-17T07:00:00Z",
#     "MarketplaceId": "A2EUQ1WTGCTBG2",
#     "FulfillmentChannel": "MFN",
#     "PaymentMethod": "Other",
#     "ShippingAddress": {
#         "City": "Lakeview",
#         "PostalCode": "B4C 4C9",
#         "isAddressSharingConfidential": "false",
#         "StateOrRegion": "Nova Scotia",
#         "Phone": "14147820763",
#         "CountryCode": "CA",
#         "Name": "kathleen betz",
#         "AddressLine1": "211 Third Avenue"
#     },
#     "IsPrime": "false",
#     "ShipmentServiceLevelCategory": "Standard"
# },


"""
 {
        "LatestShipDate": "2019-06-06T06:59:59Z",
        "OrderType": "StandardOrder",
        "PurchaseDate": "2019-05-29T12:27:33.527Z",
        "AmazonOrderId": "112-4259527-6550639",
        "IsReplacementOrder": "false",
        "LastUpdateDate": "2019-05-29T12:32:44.028Z",
        "NumberOfItemsShipped": "0",
        "ShipServiceLevel": "Std US D2D Dom",
        "OrderStatus": "Canceled",
        "SalesChannel": "Amazon.com",
        "IsBusinessOrder": "false",
        "NumberOfItemsUnshipped": "0",
        "PaymentMethodDetails": {
            "PaymentMethodDetail": "Standard"
        },
        "IsPremiumOrder": "false",
        "EarliestShipDate": "2019-06-04T07:00:00Z",
        "MarketplaceId": "ATVPDKIKX0DER",
        "FulfillmentChannel": "MFN",
        "IsPrime": "false",
        "ShipmentServiceLevelCategory": "Standard"
    },
"""
# def get_serializer_class(self, data):
#     if len(data) == 1:
#         return PaymentMethodDetailsSerializers
#     if len(data) == 2:
#         return OrderTotalSerializers
#     if 3 <= len(data) <= 15:
#         return ShippingAddressSerializers
#     if len(data) > 15:
#         return UpdateMysqlOrdersSerializers
#
# def create(self, data):
#     old_data = data
#     data = [data['PaymentMethodDetails'], data['OrderTotal'], data['ShippingAddress'], old_data]
#     for i in range(3):
#         serializer = self.get_serializer(data=data[i])
#         serializer.is_valid(raise_exception=True)
#         self.perform_create(serializer)
#         if i == 0:
#             value_id = PaymentMethodDetails.objects.all().order_by('-id').first().id
#             old_data['PaymentMethodDetails'] = value_id
#         elif i == 1:
#             value_id = Money.objects.all().order_by('-id').first().id
#             old_data['OrderTotal'] = value_id
#         elif i == 2:
#             value_id = Address.objects.all().order_by('-id').first().id
#             old_data['ShippingAddress'] = value_id
#
#     headers = self.get_success_headers(serializer.data)
#     return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)//////////////////////////////////////////////////////////////////
# demo = "tap:AMP.setState({\n                                detailSkuState: {\n                                    curPropertyIds: detailSkuState.curPropertyIds.map((item,index) => index == 0 ? 'u193' : item),\n                                                                                                                                                    skuProperty: detailSkuState.skuProperty.map((item,index) => index == 0 ? 'BLACK' : item)\n                                                                    },\n                                cid: cid.map((item,index) => index == 0 ? 193 : item)\n                            }), shipping-fees.submit\n                                                            , sku-carousel.goToSlide(index=0)\n                                                                                                                    "
# print(demo)
#
# result = re.search(r"skuProperty[^\']*([^\:]*)", demo)
# if result:
#     print(result.group(1))
# else:
#     print('未匹配到数据')

import datetime
import os
import random
import urllib

from pprint import pprint

from lxml import etree

import xmltodict
from django.db import transaction
from django.db.models import Q
from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
import json
import time

import requests
import pymysql
from mws import mws, Feeds
from rest_framework import status
from rest_framework.generics import GenericAPIView, ListAPIView, CreateAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.views import APIView

from orders.models import Orders, PaymentExecutionDetailItem, OrdersMoney, Address, PaymentMethodDDetails, Invoice, \
    OrdersItemMoney, TaxCollection, ProductInfos, OrderItem, UpdateTime, CustomsDeclarationInfos
from orders.serializers import StoreSerializer, OrderListSerializer, UpdateMysqlOrdersSerializers, \
    PaymentMethodDetailsSerializers, OrderTotalSerializers, ShippingAddressSerializers, UpdateMysqlOrdersSerializers2, \
    InvoiceDataSerializer, OrderItemsSerializer2, OrderItemsSerializer1, \
    OrderItemMoneySerializer, ProductInfoSerializer, TaxCollectionSerializer, OrderItemsSerializer3, \
    OrderItemListSerializer, UpdateTimeSerializer, OrderStatuAndTrackingSeiralizer, OrderItemOfOneSerializer, \
    OrderItemDictOfOneSerializer, OrderItemForCustomsDeclarationInfosSerializer, CustomsDeclarationInfosSerializer, \
    OrderAddressSerializer, OrderItemCustomDec, TrackingNumSerializer
from store.models import StoreManagement
from users.models import User
from vne_erp.settings.dev1 import BASE_DIR
from vne_erp.utils.exceptions import logger
from vne_erp.utils.fastdfs.fdfs_storage import FasfDFSStorage
from vne_erp.utils.iosformat import isoformat
from vne_erp.utils.script_for_xiaomi import ScriptForXiaomi
import string

from vne_erp.utils.user_agent_and_ip_proxy import IP_PROXY_LIST, USER_AGENT_LIST

access_key = 'AKIAJGOQGGTWX4ICHVZQ'  # replace with your access key

marketplaceids = ['A1AM78C64UM0Y8', 'A2EUQ1WTGCTBG2', 'ATVPDKIKX0DER']

secret_key = 'SjLuwkvF46VCiPzmlFwP8+aPYjA7BNP3IazSyD0l'  # replace with your secret key

global update_status
global update_list
update_list = list()
update_status = str()
#  -*-coding:utf8 -*-

def get_order_item(AmazonOrderId, store_id):
    """获取单个OrderItem"""
    # try:
    #     order_info = Orders.objects.get(AmazonOrderId=str(AmazonOrderId))
    # except Exception as e:
    #     return Response({'error_msg': str(e) + '1'})

    try:
        store_info = StoreManagement.objects.get(id=store_id)
    except Exception as e:
        return Response({'error_msg': str(e) + "2"})
    staff_id = store_info.staff

    try:
        staff_info = User.objects.get(id=staff_id.id)
    except Exception as e:
        return Response({'error_msg': str(e) + '3'})

    staff_name = staff_info.username
    SellerId = store_info.seller_id if store_info.seller_id != '' else ''
    MWSToken = store_info.mws_token if store_info.mws_token != '' else ''
    x = mws.Orders(access_key=access_key, secret_key=secret_key, account_id=SellerId, auth_token=MWSToken)
    orders = x.list_order_items(amazon_order_id=AmazonOrderId)
    response_data = orders.original
    xml_dict = xmltodict.parse(response_data)

    staff_info = {'staff_id': staff_id.id, 'staff_name': staff_name}
    store_info = {'store_name': store_info.store}
    xml_dict['staff_info'] = staff_info
    xml_dict['store_info'] = store_info
    xml_dict = xml_dict['ListOrderItemsResponse']['ListOrderItemsResult']['OrderItems']

    return xml_dict


def order_item_data_to_mysql1(data,order_id):

    p_serializer = ProductInfoSerializer(data=data["ProductInfo"])
    p_serializer.is_valid()
    p_serializer.save()
    order_item_money_id = ProductInfos.objects.all().order_by('-id').first().id

    data["ProductInfo"] = order_item_money_id
    data['IsTransparency'] = string.capwords(data['IsTransparency'])
    data['IsGift'] = string.capwords(data['IsGift'])
    data['OrderId'] = order_id



    serializer = OrderItemsSerializer2(data=data)
    serializer.is_valid()
    serializer.validated_data
    serializer.save()


def field_serializer(data):
    """对item_money外键字段字段进行校验"""
    fields = ['ItemPrice', 'ShippingPrice', 'GiftWrapPrice', 'ItemTax', 'ShippingTax', 'GiftWrapTax', 'ShippingDiscountTax',
     'ShippingDiscount', 'PromotionDiscountTaxPromotionDiscount', 'CODFee', 'CODFeeDiscount']

    for i in fields:
        if i in data.keys:
            item_money_serializer = OrderItemMoneySerializer(data=data[i])
            item_money_serializer.is_valid()
            item_money_serializer.save()
            fields_item_money_id = OrdersItemMoney.objects.all().order_by('-id').first().id
            data[i] = fields_item_money_id


def order_item_data_to_mysql2(data,order_id):

    fields = ['ItemPrice', 'ShippingPrice', 'GiftWrapPrice', 'ItemTax', 'ShippingTax', 'GiftWrapTax',
              'ShippingDiscountTax',
              'ShippingDiscount', 'PromotionDiscountTax', 'PromotionDiscount', 'CODFee', 'CODFeeDiscount']
    data_key_list = list()
    for j in data:
        data_key_list.append(j)

    for i in fields:
        if i in data_key_list:

            item_money_serializer = OrderItemMoneySerializer(data=data[i])
            item_money_serializer.is_valid(raise_exception=True)
            item_money_serializer.save()
            fields_item_money_id = OrdersItemMoney.objects.all().order_by('-id').first().id
            data[i] = fields_item_money_id
        else:
            data[i] = None

    produc_serializer = ProductInfoSerializer(data=data["ProductInfo"])
    produc_serializer.is_valid()
    produc_serializer.save()
    order_item_money_id = ProductInfos.objects.all().order_by('-id').first().id
    data["ProductInfo"] = order_item_money_id

    data['IsTransparency'] = string.capwords(data['IsTransparency'])
    data['IsGift'] = string.capwords(data['IsGift'])
    data['OrderId'] = order_id

    if "TaxCollection" in data.keys():
        # print("有TaxCollection字段")
        t_serializer = TaxCollectionSerializer(data=data["TaxCollection"])
        # print(t_serializer.data)
        t_serializer.is_valid()
        t_serializer.save()
        TaxCollection_id = TaxCollection.objects.all().order_by('-id').first().id
        data["TaxCollection"] = TaxCollection_id
        serializerx = OrderItemsSerializer1(data=data)
        serializerx.is_valid()
        serializerx.save()
        return
    serializerx = OrderItemsSerializer3(data=data)
    serializerx.is_valid(raise_exception=True)
    serializerx.save()


@transaction.atomic
def data_to_mysql1(data,store_id):
    # 传入order_list数据并存入mysql
    save_id = transaction.savepoint()
    try:

        serializer2 = OrderTotalSerializers(data=data['OrderTotal'])
        serializer2.is_valid()
        serializer2.save()
        value_id2 = OrdersMoney.objects.all().order_by('-id').first().id

        serializer3 = PaymentMethodDetailsSerializers(data=data['PaymentMethodDetails'])
        serializer3.is_valid()
        serializer3.save()
        value_id3 = PaymentMethodDDetails.objects.all().order_by('-id').first().id

        if 'AddressLine1' not in data['ShippingAddress'].keys():
            data['ShippingAddress']['AddressLine1'] = '暂无'
        if 'AddressLine2' not in data['ShippingAddress'].keys():
            data['ShippingAddress']['AddressLine2'] = '暂无'
        if 'AddressLine3' not in data['ShippingAddress'].keys():
            data['ShippingAddress']['AddressLine3'] = '暂无'
        if 'AddressType' not in data['ShippingAddress'].keys():
            data['ShippingAddress']['AddressType'] = '暂无'
        if 'Country' not in data['ShippingAddress'].keys():
            data['ShippingAddress']['Country'] = '暂无'
        if 'District' not in data['ShippingAddress'].keys():
            data['ShippingAddress']['District'] = '暂无'
        if 'Phone' not in data['ShippingAddress'].keys():
            data['ShippingAddress']['Phone'] = '暂无'
        if 'isAddressSharingConfidential' in data['ShippingAddress'].keys():
            data['ShippingAddress']['isAddressSharingConfidential'] = string.capwords(
                data['ShippingAddress']['isAddressSharingConfidential'])

        serializer1 = ShippingAddressSerializers(data=data['ShippingAddress'])
        serializer1.is_valid()
        serializer1.save()
        value_id1 = Address.objects.all().order_by('-id').first().id

        now_time = datetime.datetime.now().strftime("%Y%m%D%H%m%S")[12:]
        data['MerchantOrderID'] = "TQ" + now_time + "1"
        data['MerchantOrderItemID'] = "TQ" + now_time + "2"
        data['MerchantFulfillmentID'] = "TQ" + now_time + "3"
        data['MerchantFulfillmentItemID'] = "TQ" + now_time + "4"

        data['PaymentMethodDetails'] = value_id3
        # data['OrderItemId'] = OrderItemId
        data['OrderTotal'] = value_id2
        data['ShippingAddress'] = value_id1

        serializer = UpdateMysqlOrdersSerializers(data=data)
        serializer.is_valid()
        serializer.save()
    except Exception as e:
        logger.error(e)
        transaction.savepoint_rollback(save_id)

    order_id = Orders.objects.all().order_by("-id").first()
    xml_dict = get_order_item(data["AmazonOrderId"], store_id)

    if isinstance(xml_dict['OrderItem'], list):
        print(xml_dict['OrderItem'])

        for j in xml_dict['OrderItem']:
            j['AmazonOrderId'] = data["AmazonOrderId"]
            if j["QuantityOrdered"] == "0":
                order_item_data_to_mysql1(j, order_id)
            else:
                order_item_data_to_mysql2(j, order_id)
    else:
        xml_dict['OrderItem']['AmazonOrderId'] = data["AmazonOrderId"]
        if xml_dict['OrderItem']["QuantityOrdered"] == '0':
            order_item_data_to_mysql1(xml_dict['OrderItem'], order_id)
        else:
            order_item_data_to_mysql2(xml_dict['OrderItem'], order_id)

    transaction.savepoint_commit(save_id)


@transaction.atomic
def data_to_mysql2(data, store_id):
    save_id = transaction.savepoint()
    try:


        # 传入order_list数据并存入mysql
        serializer3 = PaymentMethodDetailsSerializers(data=data['PaymentMethodDetails'])
        serializer3.is_valid()
        serializer3.save()
        value_id3 = PaymentMethodDDetails.objects.all().order_by('-id').first().id

        now_time = datetime.datetime.now().strftime("%Y%m%D%H%m%S")[12:]
        data['MerchantOrderID'] = "TQ" + now_time + "1"
        data['MerchantOrderItemID'] = "TQ" + now_time + "2"
        data['MerchantFulfillmentID'] = "TQ" + now_time + "3"
        data['MerchantFulfillmentItemID'] = "TQ" + now_time + "4"

        data['PaymentMethodDetails'] = value_id3
        # data['OrderItemId'] = OrderItemId

        serializer = UpdateMysqlOrdersSerializers2(data=data)
        serializer.is_valid()
        serializer.save()
    except Exception as e:
        logger.error(e)
        transaction.savepoint_rollback(save_id)

    order_id = Orders.objects.all().order_by("-id").first()
    xml_dict = get_order_item(data["AmazonOrderId"], store_id)

    if isinstance(xml_dict['OrderItem'], list):
        print(xml_dict['OrderItem'])

        for j in xml_dict['OrderItem']:
            j['AmazonOrderId'] = data["AmazonOrderId"]
            if j["QuantityOrdered"] == "0":
                order_item_data_to_mysql1(j, order_id)
            else:
                order_item_data_to_mysql2(j, order_id)
    else:
        xml_dict['OrderItem']['AmazonOrderId'] = data["AmazonOrderId"]
        if xml_dict['OrderItem']["QuantityOrdered"] == '0':
            order_item_data_to_mysql1(xml_dict['OrderItem'], order_id)
        else:
            order_item_data_to_mysql2(xml_dict['OrderItem'], order_id)

    transaction.savepoint_commit(save_id)


class UpdateMysqlOrders(APIView):

    def get(self, request):
        # 1 获取所有SellerId MWSAuthToken

        # 既然是更新订单就得覆盖原订单列表  首先删除原订单 再做新的查询入库工作            错误思想

        # Orders.objects.all().delete()
        # Address.objects.all().delete()
        # PaymentMethodDDetails.objects.all().delete()
        # OrdersMoney.objects.all().delete()
        #
        # OrderItem.objects.all().delete()
        # TaxCollection.objects.all().delete()
        # ProductInfos.objects.all().delete()
        # OrdersItemMoney.objects.all().delete()

        """
        既然是更新订单就得以 上次更新时间为开始时间   现在时间为结束时间 开始更新   所以得有一个字段记录更新时间
        CreatedAfter = 数据库查询上次的更新时间
        CreateBefore = datetime.datetime.now()

        # """
        global update_list
        global update_status
        update_list = []
        update_status = '更新中...'
        if len(Orders.objects.all()) == 0:
            order_update_time = datetime.datetime(2019, 1, 1)
        else:
            order_update_time = UpdateTime.objects.all().last().order_update_time

        CreatedAfter = isoformat(order_update_time)
        print(CreatedAfter)

        data_str_list = list()

        store_info = StoreManagement.objects.all()
        # 2 遍历每一组 SellerId MWSAuthToken  发起请求 获取响应数据
        for i in store_info:
            data_dict = dict()
            SellerId = i.seller_id if i.seller_id != '' else ''
            MWSToken = i.mws_token if i.mws_token != '' else ''
            staff_id = i.staff_id
            store_id = i.id
            store_name = i.store
            staff_name = User.objects.filter(id=staff_id)[0].username
            time.sleep(1)

            print(store_name,access_key,secret_key,SellerId,MWSToken,type(SellerId), type(MWSToken))
            x = mws.Orders(access_key=access_key, secret_key=secret_key, account_id=str(SellerId), auth_token=str(MWSToken))
            try:
                orders = x.list_orders(created_after=CreatedAfter, marketplaceids=marketplaceids)
            except Exception as e:
                return Response({"error_msg": str(e)})

            response_data = orders.original
            xml_dict = xmltodict.parse(response_data)
            staff_info = {'staff_id': staff_id, 'staff_name': staff_name}
            store_info = {'store_name': store_name}
            xml_dict['store_info'] = store_info
            xml_dict['staff_info'] = staff_info
            xml_dict = xml_dict["ListOrdersResponse"]["ListOrdersResult"]['Orders']

            if xml_dict is not None:

                for j, k in xml_dict.items():

                    for o in k:
                        # print("111", o)
                        o['SellerStore'] = i.id
                        if o['OrderStatus'] == 'Shipped':
                            data_to_mysql1(o, store_id)
                        elif o['OrderStatus'] == 'Unshipped':
                            data_to_mysql1(o, store_id)
                        elif o['OrderStatus'] == 'Canceled':
                            data_to_mysql2(o, store_id)
                        else:
                            pass
                data_str = store_name + "同步成功，更新" + str(len(xml_dict["Order"])) + "条订单"
                data_str_list.append(data_str)
                update_list = data_str_list
                print(update_list)
            else:
                data_str = store_name + "同步成功，更新0条订单"
                data_str_list.append(data_str)

                update_list = data_str_list
                print(update_list)

        now_time = (datetime.datetime.now() - datetime.timedelta(minutes=2)).strftime("%Y-%m-%d %H:%M")
        order_update_time = {"order_update_time": now_time}
        serializer = UpdateTimeSerializer(data=order_update_time)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        update_status = "更新完毕"
        # 4 由响应数据组成订单列表返回给前端展示
        return Response({"success_msg": "更新成功"})


